package com.helloniu.fl {

import flash.events.*;
import flash.net.*;
import flash.utils.ByteArray;

/**
usage: @see FileUploader
**/
public class ByteWebHandler {
    /**
     * Unknown state.
     */
    public static const UNKNOWN:Number = -3;
    /**
     * Transaction failed
     */
    public static const TRANSACTION_FAILED:Number = -2;
    /**
     * Commnunication failed.
     */
    public static const COMMUNICATION_FAILED:Number = -1;
    /**
     * Commnunication successful.
     */
    public static const COMMUNICATION_SUCCESSFUL:Number = 0;

    /**
     * Constructor.
     */
    public function ByteWebHandler() {
    }

    /**
     * Set request data.
     */
    public function setReqData(areqData:ByteArray):void {
       this.reqData = areqData;
    }

    /**
     * Get request data.
     */
    public function getReqData():ByteArray {
       return this.reqData;
    }

    /**
     * Set request URL.
     */
    public function setReqURL(areqURL:String):void {
       this.reqURL = areqURL;
    }

    /**
     * Get request URL.
     */
    public function getReqURL():String {
       return this.reqURL;
    }

    /**
     * Set communication state.
     */
    private function setState(astate:Number):void {
        state = astate;
    }

    /**
     * Get communication state.
     */
    public function getState():Number {
        return state;
    }

    /**
     * Get the response data.
     */
    public function getResData():ByteArray {
        return resData;
    }

    /**
     * Execute communication.
     */
    public function executeCommunication(acallback:Function = null):void {
        this.callback = acallback;

        loader = new URLLoader();
        var request:URLRequest = new URLRequest(getReqURL());
        request.contentType = "application/octet-stream";
        request.method = URLRequestMethod.POST;
        loader.dataFormat = URLLoaderDataFormat.BINARY;
        request.data = getReqData();

        if(callback != null) {
            var events:Array = eventsToHandle;
            var n:int = events.length;

            for(var i:int = 0; i < n; i++) {
                loader.addEventListener(events[i], eventHandler, false, 0, false);
            }
        }

        state = ByteWebHandler.UNKNOWN;
        loader.load(request);
    }


    /**
     *  Strings of the events to listen for.
     */
    private function get eventsToHandle():Array {
        return [ Event.COMPLETE, IOErrorEvent.IO_ERROR,
            SecurityErrorEvent.SECURITY_ERROR ];
    }

    /**
     * Communication over handler.
     */
    private function eventHandler(event:Event):void {
        var events:Array = eventsToHandle;
        var n:int = events.length;

        for(var i:int = 0; i < n; i++) {
            loader.removeEventListener(events[i], eventHandler);
        }

        var etype:String = event.type;

        if(etype != events[0]) {
            setState(ByteWebHandler.COMMUNICATION_FAILED);
        }
        else {
            resData = loader.data;
            state = COMMUNICATION_SUCCESSFUL;
        }

        if(callback != null) {
            (callback as Function).call(null, this);
        }
    }

    private var state:Number;
    private var reqURL:String;
    private var reqData:ByteArray;
    private var resData:ByteArray;
    private var callback:Function;
    private var loader:URLLoader;
}
}